package com.dashan.backend.datastore;

import static com.dashan.Constants.*;

import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;


import javax.jdo.annotations.Embedded;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.dashan.backend.XmlDeserializable;
import com.dashan.backend.XmlSerializable;
import com.google.appengine.api.datastore.Key;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class DsUserProfile implements XmlSerializable, XmlDeserializable {
    public enum Gender {
        Male(MALE), 
        Female(FEMALE), 
        Secret(SECRET);
        private static final Map<String, Gender> lookup = new HashMap<String, Gender>();
        static { for(Gender g : EnumSet.allOf(Gender.class)) {lookup.put(g.getName(), g);} }
        private String name;
        private Gender(String name) { this.name = name; }
        public String getName() { return name; }
        public static Gender get(String name) { return lookup.get(name); }
    }
    
    @SuppressWarnings("unused")
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;
    
    @Persistent
    private String userName = "";

    @Persistent
    private String name = "";
    
    @Persistent
    private String gender = Gender.Secret.getName();
    
    @Persistent
    @Embedded
    private DsHometown hometown;
    
    @Persistent
    @Embedded
    private DsWork work;
    
    @Persistent
    @Embedded
    private DsUniversity university;
    
    @Persistent
    @Embedded
    private DsHighSchool highSchool;
    
    public DsUserProfile(String userName) {
        this.userName = userName;
    }

    public DsHometown getHometown() {
        return hometown;
    }

    public void setHometown(DsHometown hometown) {
        this.hometown = hometown;
    }

    public DsWork getWork() {
        return work;
    }

    public void setWork(DsWork work) {
        this.work = work;
    }

    public DsUniversity getUniversity() {
        return university;
    }

    public void setUniversity(DsUniversity university) {
        this.university = university;
    }

    public DsHighSchool getHighSchool() {
        return highSchool;
    }

    public void setHighSchool(DsHighSchool highSchool) {
        this.highSchool = highSchool;
    }

    public void setGender(Gender gender) {
        this.gender = gender.getName();
    }

    public Gender getGender() {
        return Gender.get(gender);
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    
    public String getUserName() {
        return userName;
    }
    
    @Override
    public Element getXmlElement(Document xmlDoc) {
        Element root = xmlDoc.createElement("profile");
        Element ele = null;
        
        ele = xmlDoc.createElement("name");
        ele.appendChild(xmlDoc.createTextNode(name));
        root.appendChild(ele);

        ele = xmlDoc.createElement("gender");
        ele.appendChild(xmlDoc.createTextNode(gender));
        root.appendChild(ele);
        
        if (hometown != null) {
            root.appendChild(hometown.getXmlElement(xmlDoc));
        }
        if (work != null) {
            root.appendChild(work.getXmlElement(xmlDoc));
        }
        if (university != null) {
            root.appendChild(university.getXmlElement(xmlDoc));
        }
        if (highSchool != null) {
            root.appendChild(highSchool.getXmlElement(xmlDoc));
        }
        
        return root;
    }
    
    @Override
    public void fromXmlElement(Element ele) {
        
        NodeList nodeList = ele.getChildNodes();

        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                if (node.getNodeName().compareTo("name") == 0) {
                    name = ((Element) node).getFirstChild().getNodeValue();
                } else if (node.getNodeName().compareTo("gender") == 0) {
                    gender = ((Element) node).getFirstChild().getNodeValue();
                } else if (node.getNodeName().compareTo("hometown") == 0) {
                    if (hometown == null) {
                        hometown = new DsHometown();
                    }
                    hometown.fromXmlElement((Element) node);
                } else if (node.getNodeName().compareTo("work") == 0) {
                    if (work == null) {
                        work = new DsWork();
                    }
                    work.fromXmlElement((Element) node);
                } else if (node.getNodeName().compareTo("university") == 0) {
                    if (university == null) {
                        university = new DsUniversity();
                    }
                    university.fromXmlElement((Element) node);
                } else if (node.getNodeName().compareTo("highSchool") == 0) {
                    if (highSchool == null) {
                        highSchool = new DsHighSchool();
                    }
                    work.fromXmlElement((Element) node);
                } 
            }
        }
    }
    
    @Override
    public String toString() {
        return String.format("%s:%s,%s,\n{%s},\n{%s},\n{%s}", 
                        userName, name, gender, 
                        (hometown == null) ? "" : hometown.toString(),
                        (work == null) ? "" : work.toString(),
                        (university == null) ? "" : university.toString(),
                        (highSchool == null) ? "" : highSchool.toString());
               
    }
}
